package cc.linker.steplink.crm.merchant.service;

import cc.linker.steplink.crm.commons.FeeConstants;
import cc.linker.steplink.crm.commons.TradeTypeConstants;
import cc.linker.steplink.crm.commons.constant.TlPayConstant;
import cc.linker.steplink.crm.commons.constant.WcPayConstant;
import cc.linker.steplink.crm.commons.coupon.CouponRequest;
import cc.linker.steplink.crm.commons.domain.WxUser;
import cc.linker.steplink.crm.commons.enums.IntegralEnums;
import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.model.SystemProperties;
import cc.linker.steplink.crm.commons.model.WcPayProperties;
import cc.linker.steplink.crm.commons.utils.TransactionOrderUtil;
import cc.linker.steplink.crm.merchant.common.PcCouponCustomer;
import cc.linker.steplink.crm.merchant.dao.RightDao;
import cc.linker.steplink.crm.merchant.dao.VipCustomerDao;
import cc.linker.steplink.crm.merchant.dao.mall.MallsMapper;
import cc.linker.steplink.crm.merchant.service.integral.IntegralGoodsService;
import cc.linker.steplink.crm.merchanth5.dao.VipCustomerLogDao;
import cc.linker.steplink.crm.merchanth5.dao.acs.ProtectRecordDao;
import cc.linker.steplink.crm.merchanth5.dao.acs.PurchaseProcessDao;
import cc.linker.steplink.crm.merchanth5.dao.integral.IntegralH5Dao;
import cc.linker.steplink.crm.merchanth5.pojo.VipCustomerLogPo;
import cc.linker.steplink.crm.merchanth5.pojo.acs.ProtectPo;
import cc.linker.steplink.crm.merchanth5.service.CustomerIntegralService;
import cc.linker.steplink.crm.merchanth5.service.MaiBaoLaService;
import cc.linker.steplink.crm.merchanth5.service.VipCustomerLogService;
import cc.linker.steplink.crm.merchanth5.service.acs.PurchaseProcessService;
import cc.linker.steplink.crm.merchanth5.service.redis.GoodsService;
import cc.linker.steplink.crm.merchanth5.service.tl.LedgerProcessService;
import cc.linker.steplink.crm.merchanth5.util.MD5;
import cc.linker.steplink.crm.response.GlobalException;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@EnableAsync
@Slf4j
@Service
public class VipCustomerService {

    @Autowired
    private VipCustomerDao vipCustomerDao;
    @Autowired
    private VipCustomerLogService vipCustomerLogService;
    @Autowired
    private PurchaseProcessService purchaseProcessService;
    @Autowired
    private WcPayProperties wcPayProperties;
    @Autowired
    private HttpService httpService;
    @Autowired
    private MaiBaoLaService maiBaoLaService;
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private LedgerProcessService ledgerProcessService;
    @Autowired
    private ProtectRecordDao protectRecordDao;
    @Autowired
    private RightDao rightDao;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private VipCustomerLogDao vipCustomerLogDao;
    @Autowired
    private IntegralGoodsService integralGoodsService;
    @Autowired
    private CustomerIntegralService customerIntegralService;
    @Autowired
    private IntegralH5Dao integralH5Dao;
    @Autowired
    private PcCouponCustomer pcCouponCustomer;
    @Autowired
    private CouponRequest couponRequest;
    @Autowired
    private GoodsService goodsService;

    public List<Map<String,Object>> getVipList(Map<String, Object> param) {
        List<Map<String,Object>> result = vipCustomerDao.getVipList(param);
        result.forEach(x->{
            Integer vipNum = vipCustomerDao.getVipNumById(Integer.parseInt(x.get("id").toString()));
            x.put("vipNum",vipNum);
        });
        return result;
    }

    public List<Map<String,Object>> getVipListAll(Map<String, Object> param) {
        List<Map<String,Object>> result = vipCustomerDao.getVipList(param);
        return result;
    }

    public void changeVipStatus(Map<String, Object> param) {
        // 获取当前卡片类型
        Integer status = vipCustomerDao.getVipStatusById(param);
        if(status==null){
            throw GlobalException.build("卡片不存在");
        }else if("2".equals(status.toString())){
            throw GlobalException.build("卡片已失效");
        }
        vipCustomerDao.changeVipStatus(param);
    }

    public void delVip(Map<String, Object> param) {
        int vipId = Integer.parseInt(param.get("id").toString());
        // 判断 当前会员卡是否还存在会员
        Integer vipNum = vipCustomerDao.getVipNumById(vipId);
        if(vipNum>0){
            throw GlobalException.build("当前存在开通中的会员，无法删除");
        }
        List<Map<String,Object>> goodsSecKillList = vipCustomerDao.getGoodsSecKillList(vipId);
        if (goodsSecKillList != null && goodsSecKillList.size() > 0) {
            for(Map<String,Object> goodsSecKill:goodsSecKillList){
                String vipIds = goodsSecKill.get("vipIds").toString();
                String[] vipIdSet = vipIds.split(",");
                List<String> list1=Arrays.asList(vipIdSet);
                List<String> arrList = new ArrayList<String>(list1);
                arrList.remove(Integer.toString(vipId));
                String ss = String.join(",", arrList);
                goodsSecKill.put("vipIds",ss);
                vipCustomerDao.saveGoodsSecKill(goodsSecKill);
            }
        }
        // 删除操作
        rightDao.deleteCouponRelByVipId(param.get("id").toString());
        vipCustomerDao.delVip(param);
        rightDao.deleteRelByVipId(param.get("id").toString());
        stringRedisTemplate.delete("{vip}vip:limit_num_"+param.get("id").toString());
        //删除会员卡 积分商品异常
        vipCustomerDao.updateIntegralGoods(param);
    }

    public void saveVip(Map<String, Object> param) {

        long limitNum = 0L;
        // 判断名称是否已存在
        if(StringUtils.isEmpty(param.get("name"))){
            throw GlobalException.build("名称未填写");
        }
        Integer countName = vipCustomerDao.getCountVipName(param);
        if(countName>0){
            throw GlobalException.build("名称已存在");
        }
        Integer giftsStatus = 0;
        Integer giftsIntegral = 0;
        Integer giftsGrowth = 0;
        if (!StringUtils.isEmpty(param.get("giftsStatus"))) {
            giftsStatus = Integer.valueOf(param.get("giftsStatus").toString());
        }
        if (!StringUtils.isEmpty(param.get("giftsIntegral"))) {
            giftsIntegral = Integer.valueOf(param.get("giftsIntegral").toString());
        }
        if (!StringUtils.isEmpty(param.get("giftsGrowth"))) {
            giftsGrowth = Integer.valueOf(param.get("giftsGrowth").toString());
        }
        param.put("giftsIntegral", giftsIntegral);
        param.put("giftsGrowth", giftsGrowth);
        param.put("giftStatus", giftsStatus);
        if(StringUtils.isEmpty(param.get("id"))){
            if(!StringUtils.isEmpty(param.get("limitNum"))){
                limitNum = Long.valueOf(param.get("limitNum").toString());
            }
            // 新增
            // 卡片默认状态是 暂停发卡
            param.put("status",0);
            vipCustomerDao.insertVip(param);
            if(!StringUtils.isEmpty(param.get("rightIds"))){
                String id=param.get("id").toString();
                //添加关联关系
                String rightIds = param.get("rightIds").toString();
                List<String> rightlist= Arrays.asList(rightIds.split(","));
                Map map = new HashMap();
                map.put("rightlist",rightlist);
                map.put("vipId",id);
                rightDao.insertVipRel(map);
            }

            //礼包-卡券
            if(!StringUtils.isEmpty(param.get("coupons"))){
                List<Map<String,Object>> coupons = (List<Map<String,Object>>)param.get("coupons");
                if(coupons.size()>0){
                    for(Map<String,Object> couponData:coupons){
                        couponData.put("vipId",param.get("id"));
                        rightDao.insertVipCouponRel(couponData);
                    }
                }
            }
        }else{
            // 编辑
            // 判断状态 新的商品
            String id = param.get("id").toString();
            Integer status = null;
            String loseRemark = null;
            Map<String, Object> oldVipInfo = vipCustomerDao.getVip(Integer.valueOf(id), param.get("orgId").toString());
            int oldStatus = Integer.valueOf(oldVipInfo.get("status").toString());

            if(oldStatus==2){
                if(StringUtils.isEmpty(param.get("goodsId"))){
                    // 取消购买商品
                    status=0;
                    loseRemark = "";
                }else{
                    // 获取商品当前是否被删除
                    Integer goodsDeleteStatus = vipCustomerDao.getGoodsById(param);
                    if(goodsDeleteStatus!=null && goodsDeleteStatus<1){
                        status=0;
                        loseRemark = "";
                    }
                }
            }
            param.put("status",status);
            param.put("loseRemark",loseRemark);
            vipCustomerDao.updateVip(param);

            Long newLimitNum = 0L;
            if(!StringUtils.isEmpty(param.get("limitNum"))){
                newLimitNum = Long.valueOf(param.get("limitNum").toString());
                String sLimit = stringRedisTemplate.opsForValue().get("{vip}vip:limit_num_"+id);
                if(StringUtils.isEmpty(sLimit)){
                    //老数据校准缓存
                    if(newLimitNum>0){
                        Integer vipNum = vipCustomerDao.getCustomerVipNum(Long.valueOf(id));
                        limitNum = newLimitNum-vipNum;
                    }
                }else{
                    //已经生成缓存的数据维护
                    int oldLimitNum = Integer.valueOf(oldVipInfo.get("limitNum").toString());
                    limitNum = newLimitNum - oldLimitNum;
                }
            }

            //编辑不会改
            //删除关联关系
            rightDao.deleteRelByVipId(id);
            if(!StringUtils.isEmpty(param.get("rightIds"))){
                //添加关联关系
                String rightIds = param.get("rightIds").toString();
                List<String> rightlist= Arrays.asList(rightIds.split(","));
                Map map = new HashMap();
                map.put("rightlist",rightlist);
                map.put("vipId",id);
                rightDao.insertVipRel(map);
            }

            //礼包-卡券
            rightDao.deleteCouponRelByVipId(id);
            if(!StringUtils.isEmpty(param.get("coupons"))){
                List<Map<String,Object>> coupons = (List<Map<String,Object>>)param.get("coupons");
                if(coupons.size()>0){
                    for(Map<String,Object> couponData:coupons){
                        couponData.put("vipId",id);
                        rightDao.insertVipCouponRel(couponData);
                    }
                }
            }

            // 权益变更后老用户同步变更
            vipCustomerDao.updateCustomerVipBenefit(param);
            List<String> customerIds = vipCustomerDao.getVipCustomerIdList(id);
            if(null!=customerIds && customerIds.size()>0){
                for(String cId:customerIds){
                    this.reBulidUserLogin(cId,param.get("orgId").toString());
                }
            }
            Map params = new HashMap();
            params.put("goodsContent",param.get("tip"));
            params.put("goodsName",param.get("name"));
            params.put("goodsCover",param.get("bgImage"));
            //判断积分商品是否失效
            integralGoodsService.updateGoodsToIntegralGoods(Long.valueOf(id), params, null,null);
            //异步调用清除商品缓存
            goodsService.deleteGoodsRedisByVip(id);
        }
        stringRedisTemplate.opsForValue().increment("{vip}vip:limit_num_"+param.get("id"),limitNum);
//        stringRedisTemplate.opsForValue().set(limitKey,limitNum.toString());

    }

    private void reBulidUserLogin(String customerId,String orgId){
        stringRedisTemplate.delete("home:customer_info_" + customerId);
        Integer isVip = vipCustomerLogService.getIsVip(customerId,orgId);
        String globalopenId = vipCustomerLogDao.getGlobalopenIdByCustomerId(customerId);
        if(StringUtils.isEmpty(globalopenId)){
            globalopenId = vipCustomerLogDao.getAppUserIdByCustomerId(customerId);
        }
        String key = MD5.encode(orgId + globalopenId);
        String h5User = stringRedisTemplate.opsForValue().get("login:" + key);
        if(!StringUtils.isEmpty(h5User)){
            WxUser wxUser = JSON.parseObject(h5User, WxUser.class);
            wxUser.setIsVip(isVip);
            h5User = JSON.toJSONString(wxUser);
            stringRedisTemplate.opsForValue().set("login:" + key, h5User, 15, TimeUnit.MINUTES);
        }
    }




    public void refund(Map<String, Object> param) throws Exception {
        if(StringUtils.isEmpty(param.get("id"))){
            throw GlobalException.build("参数错误");
        }
        String logId = param.get("id").toString();
        VipCustomerLogPo vipCustomerLogPo = vipCustomerLogService.vipLogInfo(Long.valueOf(logId));
        if(0 == vipCustomerLogPo.getPaymentState() || 2 != vipCustomerLogPo.getVipType()) {
            if(4 != vipCustomerLogPo.getVipType()){
                throw GlobalException.build("开通记录异常");
            }
        }
        if(vipCustomerLogPo.getRefundState() != 0){
            throw GlobalException.build("已退款");
        }

        if(vipCustomerLogPo.getIntegral()>0){
            //扣除积分
            customerIntegralService.addIntegralCustomerLog(vipCustomerLogPo.getCustomerId(),"权益卡退款", IntegralEnums.customerScore.toString(),vipCustomerLogPo.getIntegral().toString(),IntegralEnums.other.toString(),vipCustomerLogPo.getOrgId());
            //增加日志
            Map<String, Object> log = new HashMap<String, Object>();
            log.put("logId", UUID.randomUUID().toString());
            log.put("customerId", vipCustomerLogPo.getCustomerId());
            log.put("scoreValue", vipCustomerLogPo.getIntegral());
            log.put("scoreType", 6);
            log.put("actionRemark", "退款"+vipCustomerLogPo.getVipName()+",订单号："+vipCustomerLogPo.getOrderSn()+",回退"+vipCustomerLogPo.getIntegral()+"积分");
            integralH5Dao.addIntegralLog(log);
        }
        if(vipCustomerLogPo.getVipType() == 4 && vipCustomerLogPo.getAmount() == 0){
            changeRefundStatus(Long.valueOf(logId),1);
        }else{
            addRefundProtect(vipCustomerLogPo);
//        //获取退款记录
//        ProtectPo protect = vipCustomerLogService.getRefundData(vipCustomerLogPo.getOrderSn());
//        //还钱
//        protectRecordService.reduceFreeze(protect);
//        //操作退款记录为完成
//        protectRecordService.updateIsEnd(vipCustomerLogPo.getOrderSn(),1);
            if(1 == vipCustomerLogPo.getPayType()){
                String url = wcPayProperties.getPayurl() + WcPayConstant.REFUND_WCPAY;
                Map<String, Object> wxRefundParam = purchaseProcessService.getWxRefundParam(vipCustomerLogPo.getOrgId(), vipCustomerLogPo.getOrderSn(), vipCustomerLogPo.getTradeSn(), "", String.valueOf(vipCustomerLogPo.getAmount()), String.valueOf(vipCustomerLogPo.getAmount()));
                try {
                    String result = httpService.doPost(url, wxRefundParam);
                    LOGGER.info("viprefund,result===[{}]", result);
                    if (StringUtils.isEmpty(result)) {
                        throw GlobalException.build("支付网关调用失败");
                    }
                    Map parse = (Map) JSON.parse(result);
                    Integer rt = (Integer) parse.get("rt");
                    if (rt == null || rt == 0) {
//                    changeRefundStatus(Long.valueOf(logId),3);
                        LOGGER.error("vip微信退款失败："+JSON.toJSONString(result));
                        throw GlobalException.build("退款失败");
                    }else{
                        changeRefundStatus(Long.valueOf(logId),1);
                    }
                } catch (Exception e) {
                    throw GlobalException.build("支付网关调用异常");
                }
            }else if(2 == vipCustomerLogPo.getPayType() || 3 == vipCustomerLogPo.getPayType()){
                String url = wcPayProperties.getAcsurl() + TlPayConstant.TRADE_REFUND;
                Map<String, Object> req = new HashMap<>();
                // orderSn	    steplink平台对应订单ID	string
                req.put("orderSn", vipCustomerLogPo.getOrderSn());
                // customerId	退款用户ID	            string
                req.put("customerId", vipCustomerLogPo.getCustomerId());
                String notifyUrl = systemProperties.getScrmUrl() + "h5/vip/refundcallback";
                req.put("notifyUrl", notifyUrl);
                // refundOrderSn        退款id
                String refundOrderSn = TransactionOrderUtil.TYPE_REFUND + TransactionOrderUtil.getPrimaryKey();
                req.put("refundOrderSn", refundOrderSn);
                // clintType	        应用别名，测试使用yt	    string
                String alias = maiBaoLaService.getAlias(vipCustomerLogPo.getOrgId());
                req.put("clintType", alias);
                try {
                    String result = ledgerProcessService.callTlAndReturn(url, req);
                    changeRefundStatus(Long.valueOf(logId),1);
                }catch (Exception e){
                    LOGGER.error("vip通联退款失败："+JSON.toJSONString(e));
                    throw GlobalException.build("退款失败");
                }
            }else{
                throw GlobalException.build("开通记录异常");
            }
        }
    }

    /**
     * 生成退款明细记录
     */
    private void addRefundProtect(VipCustomerLogPo vipLogInfo){
        List<ProtectPo> endProtectList  = vipCustomerLogService.getProtectPoListData(vipLogInfo.getOrderSn());
        //插入表
        if(endProtectList!=null && endProtectList.size()>0){
            for (ProtectPo endProtect  : endProtectList){
                endProtect.setOrderName("退款");
                if(endProtect.getAmount()!=null && endProtect.getAmount()>0){
                    protectRecordDao.addOverRefund(endProtect);
                    Long amount = endProtect.getAmount();
                    Map<String,Object> param = new HashMap<String,Object>();
                    param.put("to",vipLogInfo.getOrgId());
                    param.put("amount",amount);
                    if(endProtect.getType()!=null && endProtect.getType()!= 9){
                        // 大b
                        protectRecordDao.reduceFreezeByOrgId(param);
                    }else if(endProtect.getType()!=null && endProtect.getType()== 9){
                        // 大b
                        protectRecordDao.addFreezeByOrgId(param);
                    }
                }
            }
        }
        //修改所有记录的结算时间
        protectRecordDao.updateEndTimeNow(vipLogInfo.getOrderSn());
    }

    /**
     * 修改退款状态
     * @param id
     * @param refundState
     */
    private void changeRefundStatus(Long id,int refundState){
        vipCustomerDao.changeRefundStatus(id,refundState);
    }


    public Map<String, Object> getVip(Integer id, String orgId, HttpServletRequest request) {
        Map<String, Object> result = vipCustomerDao.getVip(id,orgId);
        Map<String,Object> goodsInfo = new HashMap<>();
        if(result==null){
            throw GlobalException.build("权益卡已删除！");
        }
        if(!StringUtils.isEmpty(result.get("goodsId"))){
            // 查询商品信息
            Long goodsId = Long.parseLong(result.get("goodsId").toString());
            goodsInfo = vipCustomerDao.getGoodsInfoById(goodsId);
        }
        result.put("goodsInfo",goodsInfo);
        //获取权益id拼接
        String rightIds = rightDao.getRightIdsByVipId(id);
        result.put("rightIds", rightIds);

        List<Map<String, Object>> vipCoupons = vipCustomerLogDao.getVipCoupons(id.toString());
        if(null!=vipCoupons && vipCoupons.size()>0){
            for (int i = vipCoupons.size()-1; i >= 0; i--) {
                Map<String, Object> param = new HashMap<>();
                param.put("couponId", vipCoupons.get(i).get("couponId"));
                Map<String,Object> res = (Map)couponRequest.doRequest("coupon-detail", param, pcCouponCustomer.getCouponCustomerInfo(request));
                if(null == res || null == res.get("name")){
                    vipCoupons.remove(i);
                }else{
                    int maxPublishNum = 0;
                    if(null != res.get("maxPublishNum")){
                        maxPublishNum = Integer.parseInt(res.get("maxPublishNum").toString());
                    }
                    int publishNum = 0;
                    if(null != res.get("publishNum")){
                        publishNum = Integer.parseInt(res.get("publishNum").toString());
                    }
                    vipCoupons.get(i).put("name", res.get("name"));
                    vipCoupons.get(i).put("count",maxPublishNum-publishNum);
                }
            }
//            for(Map<String, Object> vipCoupon:vipCoupons){
//
//                Map<String, Object> param = new HashMap<>();
//                param.put("couponId", vipCoupon.get("couponId"));
//                Map<String,Object> res = (Map)couponRequest.doRequest("coupon-detail", param, pcCouponCustomer.getCouponCustomerInfo(request));
//                int maxPublishNum = 0;
//                if(null!=res && null!=res.get("maxPublishNum")){
//                    maxPublishNum = Integer.parseInt(res.get("maxPublishNum").toString());
//                }
//                int publishNum = 0;
//                if(null!=res && null!=res.get("publishNum")){
//                    publishNum = Integer.parseInt(res.get("publishNum").toString());
//                }
//                vipCoupon.put("name", res != null ? res.get("name") : null);
//                vipCoupon.put("count",maxPublishNum-publishNum);
//            }
        }
        result.put("coupons", vipCoupons);
        return result;
    }
}
